Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

180
Vistas
How can I minimize firestore reads in the "setUsername" scenario?

the code I have now created is working, but I think it is somehow suboptimal, as it does to many database reads As far as I understand it, the "onAuthStateChange" can be understood like an useEffect hook, which gets called whenever the user authentication state changes (login, logout). Whenever this happens, the database should be checked for the username which has been chosen by the user. But if I take a look at the console the docSnap is logged a fair amount of times which to me indicates that the function gets called more often than just when the user logs in / logs out.

enter image description here

Context Component

import { createContext } from "react/cjs/react.production.min";
import { onAuthStateChanged } from "firebase/auth";
import { doc, getDoc } from "firebase/firestore";
import { auth,db } from "./firebase";
import { useState, useEffect } from "react";

export const authContext = createContext({
  user: "null",
  username: "null",
});

export default function AuthenticationContext(props) {
  const [googleUser, setGoogleUser] = useState(null);
  const [username, setUsername] = useState(null);
  const [userID, setUserID] = useState(null);

  onAuthStateChanged(auth, (user) => {
    if (user) {
      setGoogleUser(user.displayName);
      setUserID(user.uid);
      getUsername();
    } else {
      setGoogleUser(null);
    }
  });


    const getUsername = async () => {
      const docRef = doc(db, `users/${userID}`);
      const docSnap = await getDoc(docRef);
      if(docSnap.exists()){
        setUsername(docSnap.data().username);
      }
      else{
        setUsername(null);
      }
    };
  

  return (
    <authContext.Provider value={{ user: googleUser, username: username }}>
      {props.children}
    </authContext.Provider>
  );
}

What is more, is that when I login with google and submit a username, the components do not get reevaluated - so a refresh is necessary in order for all the changes to take effect, this has something to do with me not updating state in the submitHandler of the login page. If you have some ideas on how I can do this more professionally please let me hear them. Thank you in advance!

Submit Handler on Login Page

const submitHandler = async (event) => {
    event.preventDefault();
    console.log(auth.lastNotifiedUid);
    await setDoc(doc(db, "users", auth.lastNotifiedUid), {
      displayName: user,
      username: username,
    });
    await setDoc(doc(db, "usernames", username), { uid: auth.lastNotifiedUid });
  };
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

As pointed out in the comments by Dharmaraj, you set multiple subscriptions to the authentication state. This is because you call onAuthStateChanged in the body of your component, so it is executed on every render.

To avoid this, you should wrap the function in useEffect so that you only subscribe on component mounting, and unsubscribe on unmounting:

export default function AuthenticationContext(props) {
  /* ... */
  React.useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => { /* ... */ });
    return unsubscribe;
  }, []);
  /* ... */
}
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda